package com.huitone.smspfm.oldclient.core;

import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutorService;
import java.util.regex.Pattern;

import com.bin.common.utils.FileUtils;
import com.huitone.smspfm.context.thread.AppCustomBlockingThreadPool;
import com.huitone.smspfm.oldclient.logger.ExtLogger;

/**   
* @Title: FileReadManager.java 
* @Package com.unicom.gddw.module.mt 
* @Description: TODO(用一句话描述该文件做什么) 
* @author ybliang   
* @date 2017年3月21日 上午10:36:04 
* @version V1.0   
*/
public class FileReader3 {
	
	private final static ExtLogger logger = ExtLogger.create(FileReader3.class);

	private static ConcurrentLinkedQueue<File> concurrentLinkedQueue = new ConcurrentLinkedQueue<>();
	
	private File holdFile = null;
	
	private String dirPath = null;
	
	private boolean backupFile = false;
	
	private static int count = 0 ;
	
	public static void main(String[] str) {
		
		/*File file = new File("//home//ybliang//smstest//mt//00//send_20170413100421209.xml");
		
		File file2 = new File("//home//ybliang//smstest//mt//00//send_20170413100421209.xml");
		
		boolean delete = file2.delete();
		
		System.out.println(file.exists());*/
		
		ExecutorService executorService = AppCustomBlockingThreadPool.newBlockingThreadPool(30);
		
		while (true) {
			executorService.execute(new Runnable() {
				
				@Override
				public void run() {
					
					/*SendFileMsgReader fileMsgReader = new SendFileMsgReader();
					//fileMsgReader.readFile();
					
					List<MtSms> list = fileMsgReader.readMtSms("/home/ybliang/smstest/mt", "send.*\\.xml");
					
					if (list != null && !list.isEmpty()) {
						count ++;
					}
					
					String absolutePath = fileMsgReader.getAbsolutePath();
					
					System.out.println("文件路径:" + absolutePath + " , Count: " + count);
					
					try {
						Thread.sleep(3000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					
					fileMsgReader.delete();*/
					
					FileReader3 fr = new FileReader3();
					
					File file2 = fr.getFile2("/home/ybliang/smstest/mt", "send.*\\.xml");
					
					if (file2 != null) {
						System.out.println(file2.getAbsolutePath());
						System.out.println(++ count);
					}
					
					try {
						Thread.sleep(3000);
					} catch (InterruptedException e) {
						logger.error(getClass().getSimpleName()+"fixedThreadPool1　 进程异常");
						e.printStackTrace();
					}
					
					fr.delete();
					
				}
			});
		}
	}
	
	public File getFile() {
		return holdFile;
	}
	
	public File getFile(String dirPath, String regex) {
		
		File file = new File(dirPath);
		
		if (!file.exists()) {
			return null;
		}
		
		if (file.isDirectory()) {
			
			synchronized (FileReader3.class) {


				File[] listFiles = file.listFiles(new FileFilter() {
					
					@Override
					public boolean accept(File pathname) {
						boolean result = false;
						if (pathname.isFile() 
								&& Pattern.compile(regex == null ? ".*" : regex).matcher(pathname.getName()).matches() 
								&& !pathname.getAbsolutePath().endsWith(".lock")
								&& !pathname.getAbsolutePath().endsWith(".readFlag")
								&& (System.currentTimeMillis() -pathname.lastModified()) > 1000 ) { //文件生成超过1秒以上才可以去读 ,避开其它进程并发
							File lock = new File(pathname.getAbsolutePath() + ".lock");
							boolean lockFlag = lock.exists();
							if (!lockFlag 
//									|| (lockFlag && (System.currentTimeMillis() - lock.lastModified()) > 30000// 会重复读某个文件 可能有点逻辑问题
									) { 
								File readFlag = new File(pathname.getAbsolutePath() + ".readFlag");
								if(readFlag.exists()){
									result = false;
								} else {
									result = true;
								}
							} 
						}
						return result;
					}
				});
				
				if (listFiles != null && listFiles.length > 0) {
					
					File result = listFiles[0];
					
					File lock = new File(result.getAbsolutePath() + ".lock");
					
					if (lock.exists()) {
						lock.delete();
					}
					
					try {
						lock.createNewFile();	
						logger.info("文件标记为读取状态! 文件名 "+result.getAbsolutePath());
						return holdFile = result;
						
					} catch (IOException e) {
						logger.error(getClass().getSimpleName()+"lock.createNewFile() 153　 进程异常");
						e.printStackTrace();
					}
				}
			}
			
		} else {
			return null;
		}
		
		return null;
	}

	public File getFileNew(String dirPath, String regex) {

		File file = new File(dirPath);

		if (!file.exists()) {
			return null;
		}

		if (file.isDirectory()) {

			synchronized (FileReader3.class) {

				File result = null;


				if (! concurrentLinkedQueue.isEmpty()) {

					File[] listFiles = file.listFiles(new FileFilter() {

						@Override
						public boolean accept(File pathname) {
							boolean result = false;
							if (pathname.isFile()
									&& Pattern.compile(regex == null ? ".*" : regex).matcher(pathname.getName()).matches()
									&& !pathname.getAbsolutePath().endsWith(".lock")
									&& !pathname.getAbsolutePath().endsWith(".readFlag")
									&& (System.currentTimeMillis() - pathname.lastModified()) > 1000) { //文件生成超过1秒以上才可以去读 ,避开其它进程并发
								File lock = new File(pathname.getAbsolutePath() + ".lock");
								boolean lockFlag = lock.exists();
								if (!lockFlag
//									|| (lockFlag && (System.currentTimeMillis() - lock.lastModified()) > 30000// 会重复读某个文件 可能有点逻辑问题
								) {
									File readFlag = new File(pathname.getAbsolutePath() + ".readFlag");
									if (readFlag.exists()) {
										result = false;
									} else {
										result = true;
									}
								}
							}
							if (result) {
								concurrentLinkedQueue.offer(pathname);
							}
							return result;
						}
					});

					if (!concurrentLinkedQueue.isEmpty()){
						result = concurrentLinkedQueue.poll();
					}

				} else {
					result = concurrentLinkedQueue.poll();
				}

				if (result != null) {

					File lock = new File(result.getAbsolutePath() + ".lock");

					if (lock.exists()) {
						lock.delete();
					}

					try {
						lock.createNewFile();
						logger.debug("文件标记为读取状态! 文件名 "+result.getAbsolutePath());
						return holdFile = result;

					} catch (IOException e) {
						logger.error(getClass().getSimpleName()+"lock.createNewFile() 153　 进程异常");
						e.printStackTrace();
					}
				}
			}

		} else {
			return null;
		}

		return null;
	}


	
	public File getFile2(String fileDir, String fileRegex) {
		
		boolean flag = false;
		
		if (FileUtils.isDirectory(fileDir)) {
			
			setDirPath(fileDir);
			
			List<String> subDirs = FileUtils.getSubDirs(fileDir);
			Collections.sort(subDirs);
			subDirs.add(0, fileDir);
			
			for (int i = 0 ; i < subDirs.size() ; i ++) {
//				File file = getFile(subDirs.get(i), fileRegex);
				File file = getFileNew(subDirs.get(i), fileRegex);
				if (file != null) {
					flag = true;
					break;
				}
			}
		} 
		
		if (flag) {
			return holdFile;
		} else {
			return null;
		}
	}

	
	public StringBuffer read(File file, String charsetName){
		synchronized (FileReader3.class){
			StringBuffer buffer = null;
			if (file != null) {
				File readflagFile = new File(file.getAbsolutePath() + ".readFlag");
				//已有进程在读取文件
				if (readflagFile.exists()){
					return null;
				} 
	
				try {
					readflagFile.createNewFile();
					buffer = FileUtils.read(file, charsetName);
				} catch (IOException e) {
					e.printStackTrace();
					return null;
				}

				
			}	
			return buffer;
		}
	}
	
	public String getAbsolutePath() {
		String filePath = null;
		if (holdFile != null) {
			filePath = holdFile.getAbsolutePath();
		}
		return filePath;
	}
	
	public String getFileName() {
		String fileName = null;
		if (holdFile != null) {
			fileName = holdFile.getName();
		}
		return fileName;
	}
	
	public void delete() {
		synchronized (FileReader3.class) {
			if (holdFile != null && holdFile.exists()) {
				String absolutePath = holdFile.getAbsolutePath();
				holdFile.delete();
				File lock = new File(absolutePath + ".lock");
				if (lock.exists()) {
					lock.delete();
				}
			}
		}
	}
	
	public void removeTo(String destPath) {
		synchronized (FileReader3.class) {
			if (holdFile != null && holdFile.exists()) {
				
				File file = new File(destPath);
				if (!file.exists()) {
					file.mkdirs();
				}
				
				String absolutePath = holdFile.getAbsolutePath();
				
				holdFile.renameTo(new File(destPath, holdFile.getName()));
				
				File lock = new File(absolutePath + ".lock");
				if (lock.exists()) {
					lock.delete();
				}
			}
		}
	}
	
	public boolean remove() {
		boolean result = false;
		synchronized (FileReader3.class) {
			if (holdFile != null && holdFile.exists()) {
				
				String absolutePath = holdFile.getAbsolutePath();
				
				if (backupFile) {
					
					String parentAbsolutePath = holdFile.getParentFile().getAbsolutePath();
					
//					String replaceFirst = parentAbsolutePath.replaceFirst(dirPath, dirPath + "_backup");
					String replaceFirst = dirPath + "_backup";
					
					File file = new File(replaceFirst);
					
					if (!file.exists()) {
						file.mkdirs();
					}
					
					boolean renameTo = holdFile.renameTo(new File(file, holdFile.getName()));
					int 	retryNum = 10;
					while(! renameTo && retryNum-- > 0){
						System.gc();
						renameTo =  holdFile.renameTo(new File(file, holdFile.getName()));
					}
					if (renameTo) {
						File lock = new File(absolutePath + ".lock");
						if (lock.exists()) {
							lock.delete();
						}
						File readFlag = new File(absolutePath + ".readFlag");
						if(readFlag.exists()){
							readFlag.delete();
						}
						result = true;
					} else {
						File readFlag = new File(absolutePath + ".readFlag");
						if(! readFlag.exists()){
							try {
								readFlag.createNewFile();
							} catch (IOException e) {
								logger.error(getClass().getSimpleName()+"readFlag.createNewFile()  进程异常");
								e.printStackTrace();
							}
						}
						logger.info("移动文件失败: 文件名: "+absolutePath);
					}
				} else {
					
					boolean deleted = holdFile.delete();
					int 	retryNum = 10;
					while(! deleted && retryNum-- > 0){
						System.gc();
						deleted = holdFile.delete();
					}
					if (deleted) {
						File lock = new File(absolutePath + ".lock");
						if (lock.exists()) {
							lock.delete();
						}
						File readFlag = new File(absolutePath + ".readFlag");
						if(readFlag.exists()){
							readFlag.delete();
						}
						result = true;
					} else {
						File readFlag = new File(absolutePath + ".readFlag");
						if(! readFlag.exists()){
							try {
								readFlag.createNewFile();
							} catch (IOException e) {
								logger.error(getClass().getSimpleName()+"readFlag.createNewFile() 344　 进程异常");
								e.printStackTrace();
							}
						}
					}
				}
			} else {
				result = true;
				logger.error("删除 文件 ： 文件不存在, 或 holdFile is null !");
			}
			return result;
		}
	}

	public String getDirPath() {
		return dirPath;
	}

	public void setDirPath(String dirPath) {
		this.dirPath = dirPath;
	}

	public boolean isBackupFile() {
		return backupFile;
	}

	public void setBackupFile(boolean backupFile) {
		this.backupFile = backupFile;
	}
}
